package com.itcoon.cloud.framework.webmvc.exception.handler;

import com.itcoon.cloud.framework.enums.CommonResponseCode;
import com.itcoon.cloud.framework.ex.exception.BaseException;
import com.itcoon.cloud.framework.ex.exception.BaseServiceException;
import com.itcoon.cloud.framework.ex.exception.CommonSdkException;
import com.itcoon.cloud.framework.ex.register.IErrorCodeRegister;
import com.itcoon.cloud.framework.utils.SpringUtils;
import com.itcoon.cloud.framework.webmvc.config.properties.GlobalWebConfigProperties;
import com.itcoon.cloud.framework.webmvc.response.ApiResponse;
import com.itcoon.cloud.framework.webmvc.utils.ApiResponseUtils;
import org.springframework.http.HttpStatus;

import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Optional;

public class BaseExceptionHandler implements GlobalExceptionHandler<BaseException>{

    private final GlobalWebConfigProperties properties;

    private final IErrorCodeRegister errorCodeRegister;

    public BaseExceptionHandler(GlobalWebConfigProperties properties, IErrorCodeRegister errorCodeRegister) {
        this.properties = properties;
        this.errorCodeRegister =  errorCodeRegister;
    }

    @Override
    public boolean support(Exception e) {
        return e instanceof BaseException;
    }

    @Override
    public void handle(HttpServletResponse response, BaseException e) {
        e.log();
        if(e instanceof BaseServiceException){
            BaseServiceException ex = (BaseServiceException) e;
            String message =  ex.getLocalizedMessage() == null ? errorCodeRegister.getMessage(SpringUtils.getApplicationName(), ex.getCode(), ex.getArgs()) : ex.getLocalizedMessage();
            ApiResponseUtils.writeJsonResponse(response, ApiResponse.error(ex.getCode(), message), properties.getResponse().getBizExceptionHttpStatus().value());
            return;
        }else if(e instanceof CommonSdkException){
            CommonResponseCode[] commonResponseCodes = CommonResponseCode.values();
            Optional<CommonResponseCode> responseCodeOp = Arrays.stream(commonResponseCodes).filter(c->c.getCode().equals(e.getLocalizedMessage())).findAny();
            if(responseCodeOp.isPresent()){
                CommonResponseCode responseCode = responseCodeOp.get();
                String message = errorCodeRegister.getMessage(SpringUtils.getApplicationName(),responseCode.getCode());
                ApiResponseUtils.writeJsonResponse(response, ApiResponse.error(responseCodeOp.get().getCode(), message), responseCode.getStatus().value());
                return;
            }
        }
        ApiResponseUtils.writeJsonResponse(response, ApiResponse.error(), HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}
